package main

import (
	"log"
	"net"

	"test.com/center/session"
	"test.com/fusion"
	"test.com/protocol"
)

func runLoginServerListener() {
	var addr = cfg.LoginServerListen
	log.Printf("start login server listener `%s` goroutine successfully.\n", addr)

	ln, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatalf("listen login `%s` failed, %s.\n", addr, err)
	}

	log.Printf("listen login server `%s` successfully.\n", addr)
	fusion.AllClosers.Store(ln, true)

	for !fusion.IsStopService {
		conn, err := ln.Accept()
		if err != nil {
			log.Printf("accept login `%s` failed, %s.\n", addr, err)
			continue
		}
		log.Printf("accept login server `%s` ...\n", conn.RemoteAddr())
		go fusion.SafeConnHandler(runLoginServerHandler)(conn)
	}
}

func runLoginServerHandler(conn net.Conn) {
	var obj session.LoginServerSession
	obj.InitAndStartSendCoroutine(&inst.ServiceBase, conn)
	defer func() {
		session.InstLoginServerMgr.UnregisterLoginServer(&obj)
		obj.ShutdownAndStopSendCoroutine(false)
	}()
	obj.RunRecvCoroutine(protocol.CLC_RPC_INVOKE_RESP, func(pck *fusion.NetPacket) int {
		if !checkLoginServerReadyStatus(&obj, pck.Opcode) {
			log.Printf("handle login `%s` packet ready status is invalid.\n", &obj)
			return fusion.SessionHandleUnhandle
		}
		var handler = session.LoginServerSessionHandlers[pck.Opcode]
		if handler != nil {
			return handler(&obj, pck)
		}
		var rpcHandler = session.LoginServerSessionRPCHandlers[pck.Opcode]
		if rpcHandler != nil {
			return rpcHandler(&obj, pck, fusion.ReadRPCReqMetaInfo(pck))
		}
		return fusion.SessionHandleUnhandle
	})
}

func checkLoginServerReadyStatus(obj *session.LoginServerSession, opcode int) bool {
	if opcode > protocol.FLAG_LOGIN2CENTER_MSG_NEED_REGISTER_BEGIN {
		return obj.IsReady
	}
	return true
}
